package com.kakarote.hrm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.kakarote.common.log.entity.Content;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.core.common.enums.DataAuthEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.exception.CrmException;
import com.kakarote.core.feign.admin.service.AdminService;
import com.kakarote.core.servlet.ApplicationContextHolder;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.utils.UserUtil;
import com.kakarote.hrm.common.EmployeeHolder;
import com.kakarote.hrm.common.HrmCodeEnum;
import com.kakarote.hrm.common.LanguageFieldUtil;
import com.kakarote.hrm.constant.*;
import com.kakarote.hrm.entity.BO.*;
import com.kakarote.hrm.entity.PO.*;
import com.kakarote.hrm.entity.VO.*;
import com.kakarote.hrm.mapper.HrmEmployeeMapper;
import com.kakarote.hrm.mapper.HrmEmployeePostMapper;
import com.kakarote.hrm.service.*;
import com.kakarote.hrm.service.actionrecord.impl.EmployeeActionRecordServiceImpl;
import com.kakarote.hrm.utils.EmployeeUtil;
import com.kakarote.hrm.utils.FieldUtil;
import io.seata.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 员工证书 服务实现类
 * </p>
 *
 * @author huangmingbo
 * @since 2020-05-12
 */
@Service
public class HrmEmployeePostServiceImpl extends BaseServiceImpl<HrmEmployeePostMapper, HrmEmployeeCertificate> implements IHrmEmployeePostService {

    @Autowired
    private IHrmEmployeeQuitInfoService quitInfoService;

    @Autowired
    private IHrmEmployeeService employeeService;

    @Autowired
    private IHrmEmployeeDataService employeeDataService;

    @Autowired
    private IHrmEmployeeFieldService employeeFieldService;

    @Resource
    private EmployeeActionRecordServiceImpl employeeActionRecordService;

    @Autowired
    private IHrmEmployeeAbnormalChangeRecordService abnormalChangeRecordService;

    @Autowired
    private IHrmEmployeeConcurrentPostService concurrentPostService;

    @Autowired
    private IHrmDeptService hrmDeptService;

    @Autowired
    private EmployeeUtil employeeUtil;

    @Autowired
    private AdminService adminService;

    @Autowired
    private HrmEmployeeMapper employeeMapper;

    @Autowired
    private HrmEmployeeFileServiceImpl hrmEmployeeFileService;

    @Resource IHrmExamineService hrmExamineService;

    @Resource
    private ThreadPoolTaskExecutor hrmThreadPoolExecutor;

    @Autowired
    private IHrmEmployeeDataMobilizeRecordService hrmEmployeeDataMobilizeRecordService;

    @Autowired
    private IHrmEmployeeDataChangeRecordService employeeDataChangeRecordService;


    private static final String COMPANY_AGE = "company_age";

    @Override
    public PostInformationVO postInformation(Long employeeId) {
        //兼职信息
        List<ConcurrentPostVO> concurrentPostVOList = this.getConcurrentPostList(employeeId);
        // 当数据权限为本部门及下属部门时   可查看兼职人员的兼职信息
        Integer dataAuthType = adminService.queryDataType(UserUtil.getUserId(), MenuIdConstant.EMPLOYEE_MENU_ID).getData();
        if (DataAuthEnum.THIS_DEPARTMENT_AND_SUBORDINATE.getValue().equals(dataAuthType)) {
            Collection<Long> employeeIds = employeeUtil.queryDataAuthEmpIdByMenuId(MenuIdConstant.EMPLOYEE_MENU_ID);
            if (!employeeIds.contains(employeeId)) {
                return new PostInformationVO(null, null, concurrentPostVOList);
            }
        }
        HrmEmployeeQuitInfo employeeQuitInfo = quitInfoService.lambdaQuery().eq(HrmEmployeeQuitInfo::getEmployeeId, employeeId).one();
        HrmEmployee employee = employeeService.getById(employeeId);
        List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeeId);
        JSONObject employeeModel = BeanUtil.copyProperties(employee, JSONObject.class);
        List<InformationFieldVO> informationFieldVOList = employeeService.transferInformation(employeeModel, LabelGroupEnum.POST, fieldValueList);
        Map<String, String> dataMap = new HashMap<>();
        if(fieldValueList != null && !fieldValueList.isEmpty()){
            dataMap = fieldValueList.stream().map(item ->{
                item.setFieldValue(Optional.ofNullable(item.getFieldValue()).orElse(""));
                return item;
            }).collect(Collectors.toMap(HrmEmployeeData::getFieldName, HrmEmployeeData::getFieldValue, (v1, v2) -> v1));
        }
        String timeStr = dataMap.get("join_company_time");
        if (StringUtils.isNotEmpty(timeStr) && ObjectUtil.notEqual(employee.getEntryStatus(), EmployeeEntryStatusEnum.已离职.getValue())) {
            LocalDate joinTime = LocalDate.parse(timeStr);
            long nowCompanyAge = LocalDateTimeUtil.between(joinTime.atStartOfDay(), LocalDateTime.now()).toDays() + 1;
            if (LocalDateTimeUtil.toEpochMilli(joinTime) > System.currentTimeMillis()) {
                nowCompanyAge = 0;
            }
            if (nowCompanyAge != employee.getCompanyAge()) {
                employee.setCompanyAge((int) nowCompanyAge);
                employeeService.updateById(employee);
            }
        }
//        List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeeId);
//        JSONObject employeeModel = BeanUtil.copyProperties(employee, JSONObject.class);
//        List<InformationFieldVO> informationFieldVOList = employeeService.transferInformation(employeeModel, LabelGroupEnum.POST, fieldValueList);
        //计算司龄,修改描述
        String companyAgeDesc = EmployeeUtil.computeCompanyAge(employee.getCompanyAge());
        informationFieldVOList.forEach(fieldValue -> {
            if (COMPANY_AGE.equals(fieldValue.getFieldName())) {
                fieldValue.setFieldValueDesc(companyAgeDesc);
            }
            //添加语言包key
            Map<String, String> keyMap = LanguageFieldUtil.getFieldNameKeyMap("name_resourceKey", "customField.hrmField.", fieldValue.getFieldName(), fieldValue.getSetting());
            if ("channel_id".equals(fieldValue.getFieldName())) {
                keyMap.put("fieldValueDesc", "admin.recruitChannel." + fieldValue.getFieldValueDesc());
            }
            fieldValue.setLanguageKeyMap(keyMap);
        });
        if (employee.getEmploymentForms() != null && employee.getEmploymentForms().equals(EmploymentFormsEnum.NO_OFFICIAL.getValue())) {
            informationFieldVOList.removeIf(fieldValue -> "probation".equals(fieldValue.getFieldName()));
        }

        return new PostInformationVO(informationFieldVOList, employeeQuitInfo, concurrentPostVOList);
    }

    @Override
    public PostInformationHighlightVO queryPostInformationHighlight(QueryEmployeePostInformation employeePostInformation) {
        QueryEmployeePageListBO employeePageListBO = new QueryEmployeePageListBO();
        employeePageListBO.setEmployeeName(employeePostInformation.getQueryContent());
        employeePageListBO.setPage(1L);
        employeePageListBO.setLimit(1L);
        employeePageListBO.setIsOtherInfo(true);
        employeePageListBO.setIsHighlight(true);
        BasePage<Map<String, Object>> mapBasePage =
                employeeService.fullTextSearch(employeePageListBO, Lists.newArrayList(employeePostInformation.getEmployeeId()));
        List<InformationFieldVO> informationFieldVOList = new ArrayList<>();
        JSONObject employeeQuitInfo = null;
        List<JSONObject> concurrentPostVOList = null;
        List<Map<String, Object>> list = mapBasePage.getList();
        if (!list.isEmpty()) {
            Map<String, Object> map = list.get(0);
            List<String> filedList = Lists.newArrayList("dept", "org");
            List<String> keyList = Arrays.stream(employeePageListBO.getEmployeeName().split(" ")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
            HrmEmployee employee = BeanUtil.copyProperties(map, HrmEmployee.class);
            List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeePostInformation.getEmployeeId());
            JSONObject employeeModel = BeanUtil.copyProperties(employee, JSONObject.class);
            informationFieldVOList.addAll(employeeService.transferInformation(employeeModel, LabelGroupEnum.POST, fieldValueList));
            for (InformationFieldVO informationFieldVO : informationFieldVOList) {
                if (filedList.contains(informationFieldVO.getFieldName())){
                    if ("dept".equals(informationFieldVO.getFieldName())){
                        informationFieldVO.setFormType("esText");
                        informationFieldVO.setFieldValue(map.get("deptName"));
                        informationFieldVO.setFieldValueDesc(map.get("deptName"));
                    }else if ("org".equals(informationFieldVO.getFieldName())){
                        informationFieldVO.setFormType("esText");
                        informationFieldVO.setFieldValue(map.get("orgName"));
                        informationFieldVO.setFieldValueDesc(map.get("orgName"));
                    }
                }else {
                    for (String key : keyList) {
                        if (informationFieldVO.getFieldValue() != null && informationFieldVO.getFieldValue().toString().contains(key)){
                            String replace = informationFieldVO.getFieldValue().toString().replaceAll(key, "<font color='red'>" + key + "</font>");
                            informationFieldVO.setFormType("esText");
                            informationFieldVO.setFieldValue(replace);
                            informationFieldVO.setFieldValueDesc(replace);
                        }
                    }
                }
            }
            Object quitObject = map.get("employeeQuitInfo");
            if (quitObject != null) {
                JSONObject jsonObject = JSONObject.parseObject(JSONUtil.toJsonStr(quitObject));
                Set<String> strings = jsonObject.keySet();
                strings.forEach(fieldName -> {
                    String value = jsonObject.get(fieldName).toString();
                    if (StrUtil.isNotEmpty(value)) {
                        for (String key : keyList) {
                            if (value.contains(key)){
                                String replace = value.replaceAll(key, "<font color='red'>" + key + "</font>");
                                jsonObject.put(fieldName, replace);
                            }
                        }
                    }
                });
                employeeQuitInfo = jsonObject;
            }
            Object postObject = map.get("concurrentPostVOList");
            if (postObject != null) {
                concurrentPostVOList = JSONObject.parseArray(JSONUtil.toJsonStr(postObject), JSONObject.class);
                for (int i = 0; i < concurrentPostVOList.size(); i++) {
                    JSONObject jsonObject = concurrentPostVOList.get(i);
                    Set<String> strings = jsonObject.keySet();
                    strings.forEach(fieldName -> {
                        String value = jsonObject.get(fieldName).toString();
                        if (StrUtil.isNotEmpty(value)) {
                            for (String key : keyList) {
                                if (value.contains(key)){
                                    String replace = value.replaceAll(key, "<font color='red'>" + key + "</font>");
                                    jsonObject.put(fieldName, replace);
                                }
                            }
                        }
                    });
                }
            }
        }
        return new PostInformationHighlightVO(informationFieldVOList, employeeQuitInfo, concurrentPostVOList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog updatePostInformation(UpdateInformationBO updateInformationBO) {
        Long employeeId = updateInformationBO.getEmployeeId();
        HrmEmployee oldHrmEmployee = employeeService.getById(employeeId);

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(oldHrmEmployee.getEmployeeId(), oldHrmEmployee.getEmployeeName());

        List<UpdateInformationBO.InformationFieldBO> dataList = updateInformationBO.getDataList();
        if (dataList != null) {
            List<HrmDept> deptList = hrmDeptService.lambdaQuery().list();
            Map<Long, HrmDept> deptMap = deptList.stream().collect(Collectors.toMap(HrmDept::getDeptId, Function.identity()));
            dataList.forEach(employeeData -> {
                if (employeeData.getFieldValue() != null){
                    if ("dept".equals(employeeData.getFieldName())) {
                        String deptStr = employeeData.getFieldValue().toString();
                        HrmDept hrmDept = deptMap.get(Long.parseLong(deptStr));
                        if (hrmDept != null && hrmDept.getDeptType() != 2){
                            throw new CrmException(HrmCodeEnum.THE_DEPARTMENT_SELECTION_ERROR);
                        }
                    }else if ("org".equals(employeeData.getFieldName())) {
                        String deptStr = employeeData.getFieldValue().toString();
                        HrmDept hrmDept = deptMap.get(Long.parseLong(deptStr));
                        if (hrmDept != null && hrmDept.getDeptType() != 1){
                            throw new CrmException(HrmCodeEnum.THE_ORG_SELECTION_ERROR);
                        }
                    }else if ("post_status".equals(employeeData.getFieldName())){
                        if (!UserUtil.isAdmin() && employeeData.getFieldValue().toString().equals(HrmPostStatusEnum.RETIRE.getName())){
                            throw new CrmException(HrmCodeEnum.POST_STATUS_UPDATE_ERROR);
                        }
                    }
                }
            });
        }
        Map<FiledIsFixedEnum, List<UpdateInformationBO.InformationFieldBO>> isFixedMap = dataList.stream().collect(Collectors.groupingBy(employeeData -> FiledIsFixedEnum.parse(employeeData.getIsFixed())));
        List<UpdateInformationBO.InformationFieldBO> fixedEmployeeData = isFixedMap.get(FiledIsFixedEnum.FIXED);
        JSONObject jsonObject = new JSONObject();
        fixedEmployeeData.forEach(employeeData -> jsonObject.put(employeeData.getFieldName(), FieldUtil.convertFieldValue(employeeData.getType(), employeeData.getFieldValue(), IsEnum.YES.getValue())));
        HrmEmployee employee = jsonObject.toJavaObject(HrmEmployee.class);
        if (employee.getDeptId() == null) {
            employeeService.lambdaUpdate().set(HrmEmployee::getDeptId, null).eq(HrmEmployee::getEmployeeId, employeeId).update();
        }
        if (employee.getParentId() == null) {
            employeeService.lambdaUpdate().set(HrmEmployee::getParentId, null).eq(HrmEmployee::getEmployeeId, employeeId).update();
        }
        employee.setEmployeeId(employeeId);
        Integer probation = employee.getProbation();
        if (probation != null) {
            if (probation == 0) {
                employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
                employee.setBecomeTime(employee.getEntryTime());
            } else {
                LocalDateTime dateTime = LocalDateTimeUtil.offset(employee.getEntryTime().atStartOfDay(), probation, ChronoUnit.MONTHS);
                if (dateTime.isAfter(LocalDateTimeUtil.beginOfDay(LocalDateTime.now()))) {
                    employee.setStatus(EmployeeStatusEnum.TRY_OUT.getValue());
                } else {
                    employee.setStatus(EmployeeStatusEnum.OFFICIAL.getValue());
                }
                employee.setBecomeTime(dateTime.toLocalDate());
            }
        }
        List<UpdateInformationBO.InformationFieldBO> informationFieldBOS = isFixedMap.get(FiledIsFixedEnum.NO_FIXED);
        if (informationFieldBOS == null) {
            informationFieldBOS = new ArrayList<>();
        }
        List<HrmEmployeeData> hrmEmployeeData = informationFieldBOS.stream()
                .map(field -> {
                    Object value = field.getFieldValue();
                    if (value == null) {
                        value = "";
                    }
                    field.setFieldValue(employeeFieldService.convertObjectValueToString(field.getType(), field.getFieldValue(), value.toString()));
                    return BeanUtil.copyProperties(field, HrmEmployeeData.class);
                }).collect(Collectors.toList());
        Dict kv = Dict.create().set("key", "employee_id").set("param", "label_group").set("labelGroup", LabelGroupEnum.POST.getValue()).set("value", employeeId).set("dataTableName", "wk_hrm_employee_data");
        List<HrmModelFiledVO> oldFieldList = ApplicationContextHolder.getBean(IHrmActionRecordService.class).queryFieldValue(kv);
        employeeFieldService.saveEmployeeField(hrmEmployeeData, LabelGroupEnum.POST, employeeId);
        if (null != oldHrmEmployee.getEntryTime() && !oldHrmEmployee.getEntryTime().equals(employee.getEntryTime())) {
            if (null == employee.getCompanyAgeStartTime() && null == oldHrmEmployee.getCompanyAgeStartTime()) {
                employee.setCompanyAgeStartTime(employee.getEntryTime());
            }
        }
        employeeService.saveOrUpdate(employee);
        //固定字段操作记录保存
        Content content = employeeActionRecordService.employeeFixedFieldRecord(BeanUtil.beanToMap(oldHrmEmployee), BeanUtil.beanToMap(employee), LabelGroupEnum.POST, employeeId);

        //非固定字段操作记录保存
        Content content1 = employeeActionRecordService.employeeNOFixedFieldRecord(informationFieldBOS, oldFieldList, employeeId);

        String[] split = content.getDetail().split(",");
        String[] split1 = content1.getDetail().split(",");
        operationLog.setOperationInfo(JSONUtil.toJsonStr(ArrayUtil.addAll(split1, split)));
        if (EmployeeHolder.getEmployeeInfo() != null){
            //保存员工修改记录
            HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
            record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
            record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
            record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
            record.setEmployeeId(employeeId);
            record.setRemark(String.format("员工 %s 编辑了 %s 岗位信息。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), oldHrmEmployee.getEmployeeName()));
            employeeDataChangeRecordService.addChangeRecord(record);
        }

        // 使用TransactionSynchronizationManager在事务提交后执行ES更新
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                hrmThreadPoolExecutor.execute(() -> {
                    //更新es员工数据
                    employeeService.initEmployeeEsData(Lists.newArrayList(employeeId));
                });
            }
        });
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateLeaveInformation(HrmEmployeeQuitInfo quitInfo) {
        HrmEmployee employee;
        OperationLog operationLog = new OperationLog();
        if (quitInfo.getQuitInfoId() == null) {
            boolean exists = quitInfoService.lambdaQuery().eq(HrmEmployeeQuitInfo::getEmployeeId, quitInfo.getEmployeeId()).exists();
            if (exists) {
                quitInfoService.lambdaUpdate().eq(HrmEmployeeQuitInfo::getEmployeeId, quitInfo.getEmployeeId()).remove();
//                throw new CrmException(HrmCodeEnum.THE_EMPLOYEE_HAS_ALREADY_HANDLED_THE_RESIGNATION);
            }
            Content content = employeeActionRecordService.quitRecord(quitInfo);
            employee = employeeService.getById(quitInfo.getEmployeeId());
            quitInfo.setOldStatus(employee.getStatus());
            operationLog.setOperationObject(quitInfo.getEmployeeId(), employee.getEmployeeName());
            operationLog.setOperationInfo(content.getDetail());
        } else {
            employee = new HrmEmployee();
            employee.setEmployeeId(quitInfo.getEmployeeId());
            HrmEmployeeQuitInfo old = quitInfoService.getById(quitInfo.getQuitInfoId());
            HrmEmployee hrmEmployee = employeeService.getById(quitInfo.getEmployeeId());
            operationLog.setOperationObject(hrmEmployee.getEmployeeId(), hrmEmployee.getEmployeeName());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.QUIT, BeanUtil.beanToMap(old), BeanUtil.beanToMap(quitInfo), quitInfo.getEmployeeId());
            operationLog.setOperationInfo(content.getDetail());
        }
        LocalDateTime planQuitTime = quitInfo.getPlanQuitTime().atStartOfDay();
        EmployeeEntryStatusEnum entryStatus = EmployeeEntryStatusEnum.待离职;
        if (LocalDateTimeUtil.toEpochMilli(planQuitTime) > System.currentTimeMillis()) {
            EmployeeInfo employeeInfo = employeeMapper.queryEmployeeInfoByEmployeeId(quitInfo.getEmployeeId());
            if (employeeInfo != null) {
                employee.setDeptId(employeeInfo.getDeptId());
                employee.setOrgId(employeeInfo.getOrgId());
            }
            //@author qun.xu @date 2024-03-18 @desc 发起业务流程流程
            // TODO 暂时调整为不需要审批
            Boolean hasLeaveExamine = hrmExamineService.saveHrmLeaveExamine(employee, quitInfo);
            if(hasLeaveExamine && Boolean.FALSE){
                entryStatus = EmployeeEntryStatusEnum.离职审批中;
            }
        } else {
            entryStatus = EmployeeEntryStatusEnum.已离职;
            if (ObjectUtil.isNotNull(employee.getCompanyAgeStartTime())) {
                long nowCompanyAge = LocalDateTimeUtil.between(employee.getCompanyAgeStartTime().atStartOfDay(), LocalDateTime.now()).toDays() + 1;
                employee.setCompanyAge(Convert.toInt(nowCompanyAge));
            }
            abnormalChangeRecordService.addAbnormalChangeRecord(quitInfo.getEmployeeId(), AbnormalChangeType.RESIGNATION, quitInfo.getPlanQuitTime().atStartOfDay());
        }
        employee.setEntryStatus(entryStatus.getValue());
        employeeService.updateById(employee);
        quitInfoService.saveOrUpdate(quitInfo);
        employeeService.updateEmployeePostStatus(quitInfo.getEmployeeId(),quitInfo.getQuitType() == 3 ? HrmPostStatusEnum.RETIRE.getMsg() : HrmPostStatusEnum.QUIT.getName());
        //保存员工离职资料
        List<EmployeeMaterialBO> materialList = quitInfo.getMaterialList();
        if (materialList != null && !materialList.isEmpty()){
            for (EmployeeMaterialBO materialBO : materialList) {
                AddFileBO addFileBO = new AddFileBO();
                addFileBO.setEmployeeId(employee.getEmployeeId());
                addFileBO.setSubType(materialBO.getSubType());
                addFileBO.setFileId(Long.parseLong(materialBO.getFileId()));
                hrmEmployeeFileService.addFile(addFileBO);
            }
        }
        //保存员工异动记录
        HrmEmployeeDataMobilizeRecord record = new HrmEmployeeDataMobilizeRecord();
        record.setEmployeeId(employee.getEmployeeId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setType(EmployeeDataMobilizeType.DEPART.getValue());
        record.setRemark(String.format("员工 %s 办理了 %s 的离职。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        hrmEmployeeDataMobilizeRecordService.addMobilizeRecord(record);
        // 使用TransactionSynchronizationManager在事务提交后执行ES更新
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                hrmThreadPoolExecutor.execute(() -> {
                    //更新es员工数据
                    employeeService.initEmployeeEsData(Lists.newArrayList(quitInfo.getEmployeeId()));
                });
            }
        });
        return operationLog;
    }

    @Override
    public OperationLog deleteLeaveInformation(DeleteLeaveInformationBO deleteLeaveInformationBO) {
        Long employeeId = deleteLeaveInformationBO.getEmployeeId();
        HrmEmployee hrmEmployee = employeeService.getById(employeeId);
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(hrmEmployee.getEmployeeId(), hrmEmployee.getEmployeeName());

        HrmEmployeeQuitInfo quitInfo = quitInfoService.lambdaQuery().eq(HrmEmployeeQuitInfo::getEmployeeId, employeeId).one();
        HrmEmployee employee = new HrmEmployee();
        employee.setEmployeeId(quitInfo.getEmployeeId());
        employee.setEntryStatus(EmployeeEntryStatusEnum.在职.getValue());
        employeeService.updateById(employee);
        quitInfoService.removeById(quitInfo.getQuitInfoId());
        Content content = employeeActionRecordService.cancelLeave(deleteLeaveInformationBO);
        operationLog.setOperationInfo(content.getDetail());
        // 修改postStatus字段
        employeeService.updateEmployeePostStatus(quitInfo.getEmployeeId(),HrmPostStatusEnum.ONDUTY.getName());
        hrmThreadPoolExecutor.execute(() -> {
            //更新es员工数据
            employeeService.initEmployeeEsData(Lists.newArrayList(employeeId));
        });
        return operationLog;
    }

    @Override
    public PostInformationVO postArchives() {
        Long employeeId = EmployeeHolder.getEmployeeId();
        HrmEmployeeQuitInfo employeeQuitInfo = quitInfoService.lambdaQuery().eq(HrmEmployeeQuitInfo::getEmployeeId, employeeId).one();
        HrmEmployee employee = employeeService.getById(employeeId);
        List<HrmEmployeeData> fieldValueList = employeeDataService.queryListByEmployeeId(employeeId);
        JSONObject employeeModel = BeanUtil.copyProperties(employee, JSONObject.class);
        List<HrmEmployeeField> list = employeeFieldService.lambdaQuery().eq(HrmEmployeeField::getIsHidden, 0)
                .eq(HrmEmployeeField::getLabelGroup, LabelGroupEnum.POST.getValue())
                .eq(HrmEmployeeField::getIsEmployeeVisible, 1)
                .orderByAsc(HrmEmployeeField::getSorting).list();
        List<InformationFieldVO> informationFieldVOList = employeeService.transferInformation(employeeModel, list, fieldValueList);
        //计算司龄,修改描述
        String companyAgeDesc = EmployeeUtil.computeCompanyAge(employee.getCompanyAge());
        informationFieldVOList.forEach(fieldValue -> {
            if (COMPANY_AGE.equals(fieldValue.getFieldName())) {
                fieldValue.setFieldValueDesc(companyAgeDesc);
            }
            //添加语言包key
            fieldValue.setLanguageKeyMap(LanguageFieldUtil.getFieldNameKeyMap("name_resourceKey", "customField.hrmField.", fieldValue.getFieldName(), fieldValue.getSetting()));
        });
        if (employee.getEmploymentForms() != null && employee.getEmploymentForms().equals(EmploymentFormsEnum.NO_OFFICIAL.getValue())) {
            informationFieldVOList.removeIf(fieldValue -> "probation".equals(fieldValue.getFieldName()));
        }

        return new PostInformationVO(informationFieldVOList, employeeQuitInfo, new ArrayList<>());
    }

    /**
     * 获取兼职信息
     * @param employeeId
     * @return
     */
    public List<ConcurrentPostVO> getConcurrentPostList(Long employeeId) {
        List<ConcurrentPostVO> concurrentPostVOList = new ArrayList<>();
        List<HrmEmployeeConcurrentPost> concurrentPostList = concurrentPostService.lambdaQuery().eq(HrmEmployeeConcurrentPost::getEmployeeId, employeeId).list();
        concurrentPostList.forEach(concurrentPost -> {
            ConcurrentPostVO concurrentPostVO = new ConcurrentPostVO();
            BeanUtil.copyProperties(concurrentPost, concurrentPostVO);
            //计算司龄,修改描述
            if (concurrentPost.getCompanyAgeStartTime() != null) {
                long days = concurrentPost.getCompanyAgeStartTime().until(LocalDate.now(), ChronoUnit.DAYS);
                String companyAgeDesc = EmployeeUtil.computeCompanyAge((int) days);
                concurrentPostVO.setCompanyAge(companyAgeDesc);
            }

            if (concurrentPost.getDeptId() != null) {
                DeptVO deptVO = hrmDeptService.queryById(concurrentPost.getDeptId());
                if (deptVO != null) {
                    if (deptVO.getDeptType() == 2) {
                        concurrentPostVO.setDeptName(deptVO.getName());
                        DeptVO parentDeptVO = hrmDeptService.queryById(deptVO.getParentId());
                        concurrentPostVO.setCompanyName(parentDeptVO.getName());
                        concurrentPostVO.setParentDeptId(parentDeptVO.getDeptId());
                    } else if (deptVO.getDeptType() == 1) {
                        concurrentPostVO.setCompanyName(deptVO.getName());
                        concurrentPostVO.setParentDeptId(deptVO.getDeptId());
                    }
                }
            }
            concurrentPostVOList.add(concurrentPostVO);
        });

        return concurrentPostVOList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog addOrUpdateConcurrentPost(HrmEmployeeConcurrentPostBO concurrentPostBO) {


        DeptVO deptVO = hrmDeptService.queryById(concurrentPostBO.getDeptId());
        if (deptVO != null) {
            if (deptVO.getDeptType() == 1) {
                throw new CrmException(HrmCodeEnum.THE_DEPARTMENT_SELECTION_ERROR);
            } else if (!deptVO.getParentId().equals(concurrentPostBO.getParentDeptId())) {
                throw new CrmException(HrmCodeEnum.THE_DEPARTMENT_NOT_CORRESPONDING);
            }
        }
        HrmEmployeeConcurrentPost concurrentPost = new HrmEmployeeConcurrentPost();
        BeanUtil.copyProperties(concurrentPostBO, concurrentPost);
        OperationLog operationLog = new OperationLog();
        HrmEmployee employee = employeeService.getById(concurrentPost.getEmployeeId());
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());
        if (concurrentPost.getConcurrentPostId() == null) {
            concurrentPost.setCreateUserId(UserUtil.getUserId());
            concurrentPost.setCreateTime(LocalDateTimeUtil.now());
            Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.ADD, LabelGroupEnum.CONCURRENT_POST, concurrentPost.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(ListUtil.toList(content.getDetail())));
        } else {
            concurrentPost.setUpdateUserId(UserUtil.getUserId());
            concurrentPost.setUpdateTime(LocalDateTimeUtil.now());
            HrmEmployeeConcurrentPost old = concurrentPostService.getById(concurrentPost.getConcurrentPostId());
            Content content = employeeActionRecordService.entityUpdateRecord(LabelGroupEnum.CONCURRENT_POST, BeanUtil.beanToMap(old), BeanUtil.beanToMap(concurrentPost), concurrentPost.getEmployeeId());
            operationLog.setOperationInfo(JSONUtil.toJsonStr(content.getDetail().split(",")));
        }
        concurrentPostService.saveOrUpdate(concurrentPost);
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        if (concurrentPostBO.getConcurrentPostId() == null) {
            record.setRemark(String.format("员工 %s 新建了 %s 兼职信息。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        } else {
            record.setRemark(String.format("员工 %s 修改了 %s 兼职信息。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        }
        employeeDataChangeRecordService.addChangeRecord(record);
        // 使用TransactionSynchronizationManager在事务提交后执行ES更新
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                hrmThreadPoolExecutor.execute(() -> {
                    //更新es员工数据
                    employeeService.initEmployeeEsData(Lists.newArrayList(concurrentPost.getEmployeeId()));
                });
            }
        });
        return operationLog;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperationLog deleteConcurrentPost(Long concurrentPostId) {
        HrmEmployeeConcurrentPost concurrentPost = concurrentPostService.getById(concurrentPostId);
        OperationLog operationLog = new OperationLog();
        HrmEmployee employee = employeeService.getById(concurrentPost.getEmployeeId());
        operationLog.setOperationObject(employee.getEmployeeId(), employee.getEmployeeName());

        Content content = employeeActionRecordService.addOrDeleteRecord(HrmActionBehaviorEnum.DELETE, LabelGroupEnum.CONCURRENT_POST, concurrentPost.getEmployeeId());

        operationLog.setOperationInfo(content.getDetail());
        concurrentPostService.removeById(concurrentPostId);
        //保存员工修改记录
        HrmEmployeeDataChangeRecord record = new HrmEmployeeDataChangeRecord();
        record.setType(EmployeeDataChangeType.EMPLOYEE.getValue());
        record.setSubDeptId(EmployeeHolder.getEmployeeInfo().getDeptId());
        record.setSubEmployeeId(EmployeeHolder.getEmployeeInfo().getEmployeeId());
        record.setEmployeeId(employee.getEmployeeId());
        record.setRemark(String.format("员工 %s 删除了 %s 兼职信息。", EmployeeHolder.getEmployeeInfo().getEmployeeName(), employee.getEmployeeName()));
        employeeDataChangeRecordService.addChangeRecord(record);
        // 使用TransactionSynchronizationManager在事务提交后执行ES更新
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                hrmThreadPoolExecutor.execute(() -> {
                    //更新es员工数据
                    employeeService.initEmployeeEsData(Lists.newArrayList(concurrentPost.getEmployeeId()));
                });
            }
        });
        return operationLog;

    }
}
